from rest_framework import status, permissions
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from rest_framework.views import APIView
from django.db import transaction
from django.utils import timezone
from django.core.paginator import Paginator
import logging
import json
import os
from datetime import timedelta

from .models import SystemBackup, BackupOperation
from .serializers import (
    SystemBackupSerializer, BackupCreateSerializer, BackupRestoreSerializer,
    BackupOperationSerializer, BackupListSerializer, BackupStatisticsSerializer,
    RecoveryOptionsSerializer
)
from django.db import models
from .services import BackupService, RecoveryService

logger = logging.getLogger(__name__)


class BackupListView(APIView):
    """备份列表视图"""
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        """获取备份列表"""
        try:
            # 分页参数
            page = int(request.GET.get('page', 1))
            page_size = int(request.GET.get('page_size', 20))

            # 过滤参数
            backup_type = request.GET.get('backup_type')
            status_filter = request.GET.get('status')
            is_valid = request.GET.get('is_valid')

            # 构建查询
            queryset = SystemBackup.objects.all()

            if backup_type:
                queryset = queryset.filter(backup_type=backup_type)
            if status_filter:
                queryset = queryset.filter(status=status_filter)
            if is_valid is not None:
                queryset = queryset.filter(is_valid=is_valid.lower() == 'true')

            # 分页
            paginator = Paginator(queryset, page_size)
            page_obj = paginator.get_page(page)

            # 序列化
            serializer = BackupListSerializer(page_obj.object_list, many=True)

            return Response({
                'success': True,
                'data': {
                    'backups': serializer.data,
                    'pagination': {
                        'current_page': page,
                        'total_pages': paginator.num_pages,
                        'total_count': paginator.count,
                        'page_size': page_size,
                        'has_next': page_obj.has_next(),
                        'has_previous': page_obj.has_previous()
                    }
                }
            })

        except Exception as e:
            logger.error(f"获取备份列表失败: {str(e)}", exc_info=True)
            return Response({
                'success': False,
                'message': f'获取备份列表失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class BackupCreateView(APIView):
    """创建备份视图"""
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        """创建新备份"""
        try:
            serializer = BackupCreateSerializer(data=request.data)
            if not serializer.is_valid():
                return Response({
                    'success': False,
                    'message': '参数验证失败',
                    'errors': serializer.errors
                }, status=status.HTTP_400_BAD_REQUEST)

            # 创建备份服务
            backup_service = BackupService()

            # 执行备份
            backup = backup_service.create_backup(
                user=request.user,
                backup_type=serializer.validated_data['backup_type'],
                description=serializer.validated_data['description'],
                options={
                    'include_menu_data': serializer.validated_data['include_menu_data'],
                    'include_permission_data': serializer.validated_data['include_permission_data'],
                    'include_file_data': serializer.validated_data['include_file_data'],
                    'include_config_data': serializer.validated_data['include_config_data']
                }
            )

            # 返回结果
            backup_serializer = SystemBackupSerializer(backup)
            return Response({
                'success': True,
                'message': '备份创建成功',
                'data': {
                    'backup': backup_serializer.data
                }
            })

        except Exception as e:
            logger.error(f"创建备份失败: {str(e)}", exc_info=True)
            return Response({
                'success': False,
                'message': f'创建备份失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class BackupRestoreView(APIView):
    """恢复备份视图"""
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        """恢复备份"""
        try:
            serializer = BackupRestoreSerializer(data=request.data)
            if not serializer.is_valid():
                return Response({
                    'success': False,
                    'message': '参数验证失败',
                    'errors': serializer.errors
                }, status=status.HTTP_400_BAD_REQUEST)

            # 创建恢复服务
            recovery_service = RecoveryService()

            # 执行恢复
            result = recovery_service.restore_backup(
                backup_id=serializer.validated_data['backup_id'],
                user=request.user,
                options={
                    'restore_menu_data': serializer.validated_data['restore_menu_data'],
                    'restore_permission_data': serializer.validated_data['restore_permission_data'],
                    'restore_file_data': serializer.validated_data['restore_file_data'],
                    'restore_config_data': serializer.validated_data['restore_config_data'],
                    'force_restore': serializer.validated_data['force_restore']
                }
            )

            return Response({
                'success': True,
                'message': '恢复成功',
                'data': result,
                'needsRefresh': True
            })

        except Exception as e:
            logger.error(f"恢复备份失败: {str(e)}", exc_info=True)
            return Response({
                'success': False,
                'message': f'恢复备份失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class RecoveryOptionsView(APIView):
    """恢复选项视图"""
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        """获取可恢复的备份选项"""
        try:
            # 获取最近30天的有效备份
            recent_backups = SystemBackup.get_recent_backups(days=30, limit=20)

            # 推荐备份（最新的完整备份）
            recommended_backup = recent_backups.filter(
                backup_type__in=['system_snapshot', 'manual'],
                status='completed'
            ).first()

            # 生成警告信息
            warnings = []
            if not recent_backups.exists():
                warnings.append("没有找到最近的备份，建议先创建备份")

            # 估算恢复时间
            estimated_time = "5-10分钟"
            if recommended_backup and recommended_backup.size_bytes > 100 * 1024 * 1024:  # 100MB
                estimated_time = "10-20分钟"

            # 受影响的组件
            affected_components = [
                "菜单系统",
                "权限配置",
                "用户界面"
            ]

            # 序列化数据
            backup_serializer = BackupListSerializer(recent_backups, many=True)

            return Response({
                'success': True,
                'data': {
                    'available_backups': backup_serializer.data,
                    'recommended_backup_id': recommended_backup.id if recommended_backup else None,
                    'warnings': warnings,
                    'estimated_restore_time': estimated_time,
                    'affected_components': affected_components
                }
            })

        except Exception as e:
            logger.error(f"获取恢复选项失败: {str(e)}", exc_info=True)
            return Response({
                'success': False,
                'message': f'获取恢复选项失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class BackupStatisticsView(APIView):
    """备份统计视图"""
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        """获取备份统计信息"""
        try:
            # 基础统计
            total_backups = SystemBackup.objects.count()
            valid_backups = SystemBackup.objects.filter(is_valid=True).count()

            # 大小统计
            total_size = SystemBackup.objects.aggregate(
                total=models.Sum('size_bytes')
            )['total'] or 0

            # 最近备份
            recent_backups = SystemBackup.objects.filter(
                created_at__gte=timezone.now() - timedelta(days=7)
            ).count()

            # 最后备份时间
            last_backup = SystemBackup.objects.filter(is_valid=True).first()
            last_backup_date = last_backup.created_at if last_backup else None

            # 类型分布
            backup_types = SystemBackup.objects.values('backup_type').annotate(
                count=models.Count('id')
            )
            types_breakdown = {item['backup_type']: item['count'] for item in backup_types}

            # 月度统计
            monthly_stats = {}
            for i in range(6):  # 最近6个月
                month_start = timezone.now().replace(day=1) - timedelta(days=30*i)
                month_end = month_start + timedelta(days=31)
                month_count = SystemBackup.objects.filter(
                    created_at__gte=month_start,
                    created_at__lt=month_end
                ).count()
                monthly_stats[month_start.strftime('%Y-%m')] = month_count

            # 格式化大小
            def format_size(size_bytes):
                if size_bytes < 1024:
                    return f"{size_bytes} B"
                elif size_bytes < 1024 * 1024:
                    return f"{size_bytes / 1024:.1f} KB"
                elif size_bytes < 1024 * 1024 * 1024:
                    return f"{size_bytes / (1024 * 1024):.1f} MB"
                else:
                    return f"{size_bytes / (1024 * 1024 * 1024):.1f} GB"

            return Response({
                'success': True,
                'data': {
                    'total_backups': total_backups,
                    'valid_backups': valid_backups,
                    'total_size_bytes': total_size,
                    'total_size_display': format_size(total_size),
                    'recent_backups_count': recent_backups,
                    'last_backup_date': last_backup_date,
                    'backup_types_breakdown': types_breakdown,
                    'monthly_backup_count': monthly_stats
                }
            })

        except Exception as e:
            logger.error(f"获取备份统计失败: {str(e)}", exc_info=True)
            return Response({
                'success': False,
                'message': f'获取备份统计失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def quick_restore(request):
    """快速恢复最新备份"""
    try:
        # 获取最新的有效备份
        latest_backup = SystemBackup.objects.filter(
            is_valid=True,
            status='completed'
        ).first()

        if not latest_backup:
            return Response({
                'success': False,
                'message': '没有找到可用的备份'
            }, status=status.HTTP_404_NOT_FOUND)

        # 创建恢复服务
        recovery_service = RecoveryService()

        # 执行快速恢复
        result = recovery_service.quick_restore(latest_backup.id, request.user)

        return Response({
            'success': True,
            'message': '快速恢复成功',
            'data': result,
            'needsRefresh': True
        })

    except Exception as e:
        logger.error(f"快速恢复失败: {str(e)}", exc_info=True)
        return Response({
            'success': False,
            'message': f'快速恢复失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def menu_tree(request):
    """获取菜单树结构"""
    try:
        from cmdb.models import MenuItem

        # 获取所有菜单项
        menus = MenuItem.objects.all().order_by('parent_id', 'id')

        # 构建树形结构
        menu_dict = {}
        root_menus = []

        # 第一遍：创建所有节点
        for menu in menus:
            menu_data = {
                'id': menu.id,
                'name': menu.name,
                'path': menu.path,
                'icon': menu.icon,
                'parent_id': menu.parent_id,
                'children': []
            }
            menu_dict[menu.id] = menu_data

            if menu.parent_id is None:
                root_menus.append(menu_data)

        # 第二遍：建立父子关系
        for menu in menus:
            if menu.parent_id is not None and menu.parent_id in menu_dict:
                parent = menu_dict[menu.parent_id]
                parent['children'].append(menu_dict[menu.id])

        return Response({
            'success': True,
            'data': {
                'tree': root_menus,
                'total_count': len(menus)
            }
        })

    except Exception as e:
        logger.error(f"获取菜单树失败: {str(e)}", exc_info=True)
        return Response({
            'success': False,
            'message': f'获取菜单树失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
